﻿using System.Text;

namespace TPXSDK.NET.Mission.Instruction;

internal class InstPODCtrl : Tokenizer
{
    public InstPODCtrl(TokenizerAdmin admin)
    {
        Admin = admin;
        KeyName = "podctrl";
        KeyValue = (int)FlyCmdId.CMD_PODCTRL;
        Usage = "podctrl act para";
        Description = @"POD control command";
    }

    public override bool Process()
    {
        var flyCmp = Admin?.Compiler; if (null == flyCmp) return false;
        var tokens = flyCmp.GetLineTokens();

        if (null == tokens || tokens.Count < 2 || tokens.Count > 4)
        {
            flyCmp.ErrorMsg = $"{KeyName} Invalid Usage";
            return false;
        }

        var cmd = new FlyCmdItem
        {
            Id = (byte)KeyValue,
            LineNum = tokens[0].Row
        };
        tokens.RemoveAt(0);// Remove cmd Name

        // 设置动作编码
        if ("snap" == tokens[0].Name)
        {
            cmd.P1 = 0;
            if (tokens.Count == 3
                && tokens[1].Type == TokenType.NUMBER
                && tokens[2].Type == TokenType.NUMBER)
            {
                cmd.P3.U32Val = Convert.ToUInt32(tokens[1].Name);
                cmd.P4.U32Val = Convert.ToUInt32(tokens[2].Name);
            }
        }
        else if ("zoom" == tokens[0].Name)
        {
            cmd.P1 = 1;
            if (tokens.Count < 2 || tokens[1].Type != TokenType.NUMBER)
            {
                return false;
            }
            cmd.P2 = FlyUtils.ToInt16(tokens[1].Name);
        }
        else if ("angle" == tokens[0].Name)
        {
            cmd.P1 = 2;
            if (tokens.Count < 3 || tokens[1].Type != TokenType.NUMBER)
            {
                flyCmp.ErrorMsg = $"{KeyName} Invalid angle param";
                return false;
            }
            cmd.P3.FloatVal = Convert.ToSingle(tokens[1].Name);
            cmd.P4.FloatVal = Convert.ToSingle(tokens[2].Name);
        }
        else if ("record" == tokens[0].Name)
        {
            cmd.P1 = 3;
            if ("start" == tokens[1].Name) cmd.P2 = 1;
            else if ("stop" == tokens[1].Name) cmd.P2 = 0;
            else
            {
                flyCmp.ErrorMsg = $"{KeyName} Invalid record param";
                return false;
            }
        }
        else if ("lidar" == tokens[0].Name)
        {
            cmd.P1 = 4;
            if ("start" == tokens[1].Name) cmd.P2 = 1;
            else if ("stop" == tokens[1].Name) cmd.P2 = 0;
            else
            {
                flyCmp.ErrorMsg = $"{KeyName} Invalid lidar param";
                return false;
            }
        }
        else if ("osd" == tokens[0].Name)
        {
            cmd.P1 = 5;
            if ("start" == tokens[1].Name) cmd.P2 = 1;
            else if ("stop" == tokens[1].Name) cmd.P2 = 0;
            else
            {
                flyCmp.ErrorMsg = $"{KeyName} Invalid OSD param";
                return false;
            }
        }
        else if ("move" == tokens[0].Name)
        {
            cmd.P1 = 6;
            if ("stop" == tokens[1].Name) cmd.P2 = 0;
            else if ("up" == tokens[1].Name) cmd.P2 = 1;
            else if ("down" == tokens[1].Name) cmd.P2 = 2;
            else if ("left" == tokens[1].Name) cmd.P2 = 3;
            else if ("right" == tokens[1].Name) cmd.P2 = 4;
            else if ("zero" == tokens[1].Name) cmd.P2 = 255;
            else
            {
                flyCmp.ErrorMsg = $"{KeyName} Invalid move param";
                return false;
            }
        }
        else if ("videosrc" == tokens[0].Name)
        {
            cmd.P1 = 7;
            if (tokens[1].Type == TokenType.NUMBER) cmd.P2 = Convert.ToByte(tokens[1].Name);
            else
            {
                flyCmp.ErrorMsg = $"{KeyName} Invalid videosrc param";
                return false;
            }
        }
        else
        {
            flyCmp.ErrorMsg = $"{KeyName} Invalid param";
            return false;
        }

        flyCmp.CmdList.Add(cmd);

        return true;
    }

    public override void Reverse(FlyCmdItem cmd, StringBuilder sb)
    {
        if (cmd.P1 == 0)
        {
            sb.AppendLine($"{KeyName} snap");
        }
        else if (cmd.P1 == 1)
        {
            sb.AppendLine($"{KeyName} zoom {cmd.P2}");
        }
        else if (cmd.P1 == 2)
        {
            sb.AppendLine($"{KeyName} angle {cmd.P3.FloatVal:F2} {cmd.P4.FloatVal:F2}");
        }
        else if (cmd.P1 == 3)
        {
            sb.AppendLine(cmd.P2 == 0 ? $"{KeyName} record stop" : $"{KeyName} record start");
        }
        else if (cmd.P1 == 4)
        {
            sb.AppendLine(cmd.P2 == 0 ? $"{KeyName} lidar stop" : $"{KeyName} lidar start");
        }
        else if (cmd.P1 == 5)
        {
            sb.AppendLine(cmd.P2 == 0 ? $"{KeyName} osd stop" : $"{KeyName} osd start");
        }
        else if (cmd.P1 == 6)
        {
            if (cmd.P2 == 0) sb.AppendLine($"{KeyName} move stop");
            else if (cmd.P2 == 1) sb.AppendLine($"{KeyName} move up");
            else if (cmd.P2 == 2) sb.AppendLine($"{KeyName} move down");
            else if (cmd.P2 == 3) sb.AppendLine($"{KeyName} move left");
            else if (cmd.P2 == 4) sb.AppendLine($"{KeyName} move right");
            else if (cmd.P2 == 255) sb.AppendLine($"{KeyName} move zero");
            else sb.AppendLine($"{KeyName} move ???");
        }
        else if (cmd.P1 == 7)
        {
            sb.AppendLine($"{KeyName} videosrc {cmd.P2}");
        }
        else
        {
            sb.AppendLine($"{KeyName} ?");
        }
    }
}
